package org.chorus;

//  **********************************************************************************
/** Class for representing the inclination of a set of values..
 *  @author Jo Wood
 *  @version 1.1.1, 20th July, 2012.
 */
//  **********************************************************************************

/* This file is part of the Chorus river bed analysis software package. Chorus is free software:
 * you can redistribute it and/or modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 * 
 * Chorus is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with this
 * source code (see COPYING included with this source code). If not, see 
 * http://www.gnu.org/licenses/.
 */
class InclinationFinder
{
	// ----------------------------- Object variables ------------------------------
	
	private int numPos, numNeg, numFlat;
	private double threshold;						// Maximum angle permitted as 'flat' (radians)
	
	// ------------------------------- Constructor ---------------------------------
	
	/** Creates a new inclination finder.
	 */
	public InclinationFinder()
	{
		numPos = 0;
		numNeg = 0;
		numFlat= 0;
		threshold = Math.PI/180;			// 1 degree.
	}

	// --------------------------------- Methods -----------------------------------
	
	/** Adds a pair of heights at a given horizontal lag from which to accumulate inclination.
	 *  Note that the order of z values is important since inclination will be calculated in the
	 *  direction from z1 to z2.
	 *  @param z1 First elevation value at the 'start' point.
	 *  @param z2 Second elevation value at the 'end' point.
	 *  @param lag Horizontal distance between the two elevation values.
	 */
	public void add(double z1, double z2, double lag)
	{
		double incAngle = Math.atan2(z1-z2,lag);
		if (incAngle > threshold)
		{
			numPos++;
		}
		else if (incAngle < -threshold)
		{
			numNeg++;
		}
		else
		{
			numFlat++;
		}
	}

	/** Reports the inclination index based on those values that have previously been added.
	 *  @return Inclination index where 0 indicates a symmetric distribution, a negative value indicating 
	 *          a tendency to be inclined towards the 'start' points, a positive value indicating
	 *          a tendency to be inclined in the direction of the end point.
	 */
	public float getInclinationIndex()
	{
		int total = numPos+numNeg+numFlat;
		if (total == 0)
		{
			return 0;
		}
		return (float)(numPos - numNeg)/total;
	}
}
